package org.budo.mongo.jdbc.driver.statement;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.mongodb.util.JSON;

import lombok.NoArgsConstructor;

/**
 * @author limingwei
 */
@NoArgsConstructor
public class StatementDocument implements Serializable {
    private static final long serialVersionUID = -5729438955753381746L;

    private ParameterProcessor parameterProcessor = new ParameterProcessor();

    private Map<String, Object> document;

    private Integer limit;

    public StatementDocument(String statementJson, Map<Integer, Object> parameterMap) {
        List<Date> parameterTemp = new ArrayList<Date>(); // 暂存特殊类型参数，第二轮再替换
        String statementParameterized = parameterProcessor.statementParameterize(statementJson, parameterMap, parameterTemp);

        Map<String, Object> statementDocument = (Map<String, Object>) JSON.parse(statementParameterized);
        Map<String, Object> replaceDateValue = (Map<String, Object>) parameterProcessor.replaceParameterValue(statementDocument, parameterTemp);

        this.document = replaceDateValue;
    }

    public StatementDocument limit(Integer limit) {
        this.limit = limit;
        return this;
    }

    public Integer getLimit() {
        if (null != this.limit) {
            return this.limit;
        }

        if (null == this.document) {
            return null;
        }

        Map<String, Object> page = (Map<String, Object>) document.get(MongoStatement.PAGE);
        if (null == page || page.isEmpty()) {
            return null;
        }

        Object limit = page.get(MongoStatement.LIMIT);
        if (null == limit || ("" + limit).trim().isEmpty()) {
            return null;
        }

        return new Integer(limit.toString());
    }

    public Integer getSkip() {
        if (null == this.document) {
            return null;
        }

        Map<String, Object> page = (Map<String, Object>) document.get(MongoStatement.PAGE);
        if (null == page || page.isEmpty()) {
            return null;
        }

        Object skip = page.get(MongoStatement.SKIP);
        if (null == skip || ("" + skip).trim().isEmpty()) {
            return null;
        }

        return new Integer(skip.toString());
    }

    public List<Map<String, Object>> getAggregatePipeline() {
        if (null == this.document) {
            return null;
        }

        return (List<Map<String, Object>>) document.get(MongoStatement.AGGREGATE_PIPELINE);
    }

    public Map<String, Object> getWhere() {
        if (null == this.document) {
            return null;
        }

        return (Map<String, Object>) document.get(MongoStatement.WHERE);
    }

    public Map<String, Object> getSort() {
        if (null == this.document) {
            return null;
        }

        return (Map<String, Object>) document.get(MongoStatement.SORT);
    }

    public List<Map<String, Object>> getInsertValues() {
        if (null == this.document) {
            return null;
        }

        return (List<Map<String, Object>>) document.get(MongoStatement.INSERT_VALUES);
    }

    public Map<String, Object> getUpdateValues() {
        if (null == this.document) {
            return null;
        }

        return (Map<String, Object>) document.get(MongoStatement.UPDATE_VALUES);
    }
}